package com.aloha.springframework.beans.factory.support;

import com.aloha.springframework.beans.BeansException;
import com.aloha.springframework.beans.factory.FactoryBean;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author DaiZhiHeng
 * @description 用于处理处理factoryBean
 * @date 2023/7/1 21:08
 */
public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {

    // 存放所有factoryBean的缓存池
    private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>();

    protected Object getCachedObjectForFactoryBean(String beanName) {
        Object object = factoryBeanObjectCache.get(beanName);
        return (object == NULL_OBJECT ? null : object);
    }

    protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName) {
        if (factory.isSingleton()) {
            Object obj = factoryBeanObjectCache.get(beanName);
            // 表明尚未创建对象
            if (obj == null) {
                obj = doGetObjectFromFactoryBean(factory, beanName);
                // 单例对象放入缓存池
                factoryBeanObjectCache.put(beanName, (obj == null ? NULL_OBJECT : obj));
            }
            return (obj == NULL_OBJECT ? null : obj);
        } else {
            return doGetObjectFromFactoryBean(factory, beanName);
        }
    }

    // 调用自定义的创建对象的方法获取对象
    private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName) {
        try {
            return factory.getObject();
        } catch (Exception e) {
            throw new BeansException("FactoryBean threw exception on object[" + beanName + "] creation", e);
        }
    }
}
